﻿using System.Collections.Generic;
using System.Xml;
using System.Data;
using SdmxMl.Helper;

namespace SdmxMl.Common
{
    /// <summary>
    /// Annotations is a reusable element provided for a collection of annotations. 
    /// </summary>
    public class AnnotationList : List<Annotation>
    {
        #region Properties

        public bool HasUrn
        {
            get
            {
            foreach (Annotation a in this)
                if (a.Url != null)
                    return true;
            return false;
            }
        }
        #endregion

        #region Construction

        public AnnotationList()
        {
        }

        public AnnotationList Clone()
        {
             AnnotationList l = new AnnotationList();
             foreach (Annotation a in this)
                 l.Add(a.Clone());
             return l;
        }

        #endregion

        #region XML serialize

        public void WriteXml(XmlTextWriter xw, string prefix, string tag)
        {
            if (Count > 0)
            {
                xw.WriteStartElement(prefix, "Annotations", null);

                // Change to annotation prefix
                prefix = "common"; 

                // All annotations
                foreach (Annotation a in this)
                {
                    xw.WriteStartElement(prefix, "Annotation", null);
                    Xmlhelper.WriteElementIfExist(xw, prefix, "AnnotationTitle", a.Title);
                    Xmlhelper.WriteElementIfExist(xw, prefix, "AnnotationType", a.Type);
                    if (a.Url != null)
                        Xmlhelper.WriteElementIfExist(xw, prefix, "AnnotationURL", a.Url.ToString());

                    a.Text.WriteXml(xw, prefix, "AnnotationText");
                    xw.WriteEndElement(); // Annotation
                }
                
                xw.WriteEndElement(); // Annotations
            }
        }
        #endregion

        #region String Representation

        public override string ToString()
        {
            if (Count == 0)
                return string.Empty;
            return string.Format("{0} Annotation(s)", Count);
        }
        #endregion // String Representation

        #region Table Representation

        /// <summary>Presents annotations as datatable</summary>
        /// <returns>a datatable representation</returns>
        public DataTable AsDataTable()
        {
            DataTable dataTable = new DataTable();
            dataTable.Columns.Add(new DataColumn("ID", typeof(string)));
            dataTable.Columns.Add(new DataColumn("Type", typeof(string)));
            dataTable.Columns.Add(new DataColumn("Title", typeof(string)));
            dataTable.Columns.Add(new DataColumn("Text", typeof(string)));
            dataTable.Columns.Add(new DataColumn("Urn", typeof(string)));

            foreach (Annotation ann in this )
                dataTable.Rows.Add(new object[] {ann.Id, ann.Type, ann.Title, ann.Text.ToString(),
                ann.Url == null ? string.Empty : ann.Url.ToString() });

            return dataTable;
        }
        #endregion

        #region Methods for text access

        public string GetTextOfAnnotationType(string type)
        {
            string t = string.Empty;
            foreach (Annotation ann in this)
                if (ann.Type == type)
                {
                    t = ann.Text.ToString();
                    break;
                }
            if (t == MultiLang.UndefinedText)
                t = string.Empty;

            return t;
        }

        public MultiLang GetInternationalizedTextOfAnnotationType(string type)
        {
            MultiLang ml = null;
            foreach (Annotation ann in this)
                if (ann.Type == type)
                {
                    ml = ann.Text;
                    break;
                }

            return ml;
        }
        #endregion

        #region for Annotation access

        public Annotation GetAnnotationType(string type)
        {
            return GetAnnotationType(type, 1);
        }

        public Annotation GetAnnotationType(string type, int instanceNb)
        {
            int count = 0;
            Annotation  a = null;
            foreach (Annotation ann in this)
                if (ann.Type == type && ++count == instanceNb)
                {
                    a = ann;
                    break;
                }

            return a;
        }

        public AnnotationList GetAllAnnotationOfType(string type, string optionalTitle)
        {
            AnnotationList a = new AnnotationList();
            foreach (Annotation ann in this)
                if (ann.Type == type && (string.IsNullOrEmpty(optionalTitle) ||
                    string.Compare(ann.Title, optionalTitle, true) == 0))
                    a.Add(ann);

            return a;
        }
        #endregion

        #region Remove

        public void RemoveAnnotationType(string type)
        {
            AnnotationList l = new AnnotationList();
            foreach (Annotation ann in this)
                if (ann.Type == type)
                    l.Add(ann);

            foreach (Annotation ann in l)
                this.Remove(ann);
        }
        #endregion
    }

    #region IAnnotationList interface definition

    public interface IAnnotationList
    {
        AnnotationList AnnotationList
        {
            get;
            set;
        }
    }
    #endregion
}
